package edu.suda.LoopCodePlus.controller;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.suda.LoopCodePlus.common.Result;
import edu.suda.LoopCodePlus.entity.Collections;
import edu.suda.LoopCodePlus.entity.Problem;
import edu.suda.LoopCodePlus.service.CollectionService;
import edu.suda.LoopCodePlus.service.ProblemService;
import edu.suda.LoopCodePlus.service.SubmissionService;
import edu.suda.LoopCodePlus.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping("/collection")
@Slf4j
public class CollectionController {
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private CollectionService collectionService;
    @Autowired
    private ProblemService problemService;
    @Autowired
    private SubmissionService submissionService;
    @GetMapping("/list")
    public Result list(HttpServletRequest request,
                       HttpServletResponse response) {
        System.out.println("收到获取个人题目集的请求");
        System.out.println("验证token");
        String token = request.getHeader("Authorization");
        Integer userId;
        try {
            DecodedJWT decodedJWT = jwtUtil.verifyToken(token);
            userId = Integer.parseInt(decodedJWT.getClaim("userId").asString());
            System.out.println("token验证成功，userId:"+userId);
        }catch (Exception e){
            System.out.println("token验证失败");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return Result.failure("token验证失败");
        }
        List<Collections> list;
        try{
            list = collectionService.findCollectionById(userId);
            if(list!=null) {
                System.out.println("题目集获取成功");
                return Result.success(list);
            }
            else {
                System.out.println("题目集获取失败");
                return Result.failure();
            }
        }catch (Exception e){
            System.out.println("题目集获取失败");
            return Result.failure();
        }
    }
    @PostMapping("/add")
    public Result add(@RequestBody Collections collection,
                      HttpServletRequest request,
                      HttpServletResponse response) throws JsonProcessingException {
        System.out.println("收到题目集新增题目/新增题目集的请求");
        System.out.println("验证token");
        String token = request.getHeader("Authorization");
        Integer userId;
        try {
            DecodedJWT decodedJWT = jwtUtil.verifyToken(token);
            userId = Integer.parseInt(decodedJWT.getClaim("userId").asString());
            System.out.println("token验证成功，userId:"+userId);
        }catch (Exception e){
            System.out.println("token验证失败");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return Result.failure("token验证失败");
        }
        Collections oldCollection;
        if(collection.getColId()!=null){
            String problemListStr =collection.getProblemList();
            ObjectMapper mapper = new ObjectMapper();
            List<Map<String, Object>> problemList = mapper.readValue(problemListStr, new TypeReference<List<Map<String, Object>>>() {});
            oldCollection = collectionService.findCollectionByColId(collection.getColId());
            try{
                if(!Objects.equals(oldCollection.getColName(), collection.getColName())){
                    for(Map<String, Object> object:problemList){
                        Problem problem = problemService.findProblemById((Integer) object.get("problemId"));
                        String collectionListStr = problem.getCollection();
                        System.out.println("当前未修改之前的题目集："+collectionListStr);
                        System.out.println(oldCollection.getColName());
                        System.out.println(collection.getColName());
                        //将旧的题目集名替换成新的题目集名
                        collectionListStr = collectionListStr.replace("\""+oldCollection.getColName()+"\"", "\""+collection.getColName()+"\"");
                        System.out.println("当前修改之后的题目集："+collectionListStr);
                        problem.setCollection(collectionListStr);
                        problemService.updateProblemById(problem.getProblemId(), userId,problem);
                    }
                }
            }catch (Exception e){
                return Result.failure("题目集名称改变，题目更新错误");
            }
            System.out.println("向题目集"+collection.getColName()+"添加题目");

            try {
                oldCollection = collectionService.findCollectionById(userId, collection.getColId());
                if(oldCollection==null) {
                    System.out.println("题目集不存在");
                    return Result.failure("原题目集已经不存在");
                }
                String oldProblemListStr = oldCollection.getProblemList();
                List<Map<String, Object>> oldProblemList = mapper.readValue(oldProblemListStr, new TypeReference<List<Map<String, Object>>>() {});
                //深拷贝
                List<Map<String, Object>> oldProblemList1 = new ArrayList<>(oldProblemList);
                List<Map<String, Object>> problemList1 = new ArrayList<>(problemList);
                problemList.removeAll(oldProblemList1);
                oldProblemList.removeAll(problemList1);
                System.out.println("待添加题目:"+problemList);
                System.out.println("待删除题目:"+oldProblemList);
                //遍历newProblemList
                for(Map<String, Object> object:problemList){
                    Integer problemId = (Integer) object.get("problemId");
                    Problem problem = problemService.findProblemById(problemId);
                    if(problem==null){
                        System.out.println(problemId+"题目不存在");
                    }
                    if(Objects.equals(problem.getUserId(), userId)){
                        String collectionListStr = problem.getCollection();
                        Set<String> collectionList = mapper.readValue(collectionListStr, new TypeReference<Set<String>>(){});
                        if(!collectionList.contains(collection.getColName())){
                            collectionList.add(collection.getColName());
                            problem.setCollection(mapper.writeValueAsString(collectionList));
                            try{
                                if(problemService.updateProblemById(problemId,userId,problem)){
                                    System.out.println(problemId+"题目集添加成功");
                                }
                                else {
                                    System.out.println(problemId+"题目集添加失败");
                                }
                            }catch (Exception e){
                                System.out.println(problemId+"题目集添加失败,数据库错误");
                                return Result.failure("题目集添加失败,数据库错误");
                            }
                        }
                    }
                }
                //遍历problemList，找出要删除该题目集的题目
                for(Map<String, Object> object:oldProblemList){
                    Integer problemId = (Integer) object.get("problemId");
                    Problem problem = problemService.findProblemById(problemId);
                    if(problem==null){
                        System.out.println("题目不存在");
                    }
                    if(Objects.equals(problem.getUserId(), userId)){
                        String collectionListStr = problem.getCollection();
                        Set<String> collectionList = mapper.readValue(collectionListStr, new TypeReference<Set<String>>(){});
                        if(collectionList.contains(collection.getColName())){
                            collectionList.remove(collection.getColName());
                            problem.setCollection(mapper.writeValueAsString(collectionList));
                            try{
                                if(problemService.updateProblemById(problemId,userId,problem)){
                                    System.out.println(problemId+"题目集删除成功");
                                }
                                else {
                                    System.out.println(problemId+"题目集删除失败");
                                }
                            }catch (Exception e){
                                System.out.println(problemId+"题目删除题目集失败,数据库错误");
                                return Result.failure("题目集删除失败,数据库错误");
                            }
                        }
                    }
                }
                try{
                    if(collectionService.updateCollection(collection)) {
                        System.out.println("题目集修改成功");
                        return Result.success("题目集修改成功");
                    }
                    else {
                        System.out.println("题目集修改失败");
                        return Result.failure("题目集修改失败");
                    }
                }catch (Exception e){
                    System.out.println("题目集修改失败");
                    return Result.failure("题目修改失败");
                }

            }catch (Exception e){
                System.out.println("题目集不存在,更新失败，数据库错误");
                return Result.failure();
            }
        }
        System.out.println("添加新的题目集"+collection.getColName());
        try{
            if(collectionService.addCollection(collection)) {
                System.out.println("题目集添加成功");
            }
            else {
                System.out.println("题目集添加失败");
                return Result.failure("题目集添加失败");
            }
        }catch (Exception e){
            System.out.println("题目集添加失败");
            return Result.failure("题目集添加失败");
        }
        String problemListStr =collection.getProblemList();
        ObjectMapper mapper = new ObjectMapper();
        List<Map<String, Object>> problemList = mapper.readValue(problemListStr, new TypeReference<List<Map<String, Object>>>() {});
        for(Map<String, Object> object:problemList){
            Integer problemId = (Integer) object.get("problemId");
            Problem problem = problemService.findProblemById(problemId);
            if(problem==null){
                System.out.println("题目不存在");
            }
            if(Objects.equals(problem.getUserId(), userId)){
                String collectionListStr = problem.getCollection();
                Set<String> collectionList = mapper.readValue(collectionListStr, new TypeReference<Set<String>>(){});
                if(!collectionList.contains(collection.getColName())){
                    collectionList.add(collection.getColName());
                    problem.setCollection(mapper.writeValueAsString(collectionList));
                    try{
                        if(problemService.updateProblemById(problemId,userId,problem)){
                            System.out.println(problemId+"题目添加题目集添加成功");
                        }
                        else {
                            System.out.println(problemId+"题目添加题目集添加失败");
                        }
                    }catch (Exception e){
                        System.out.println(problemId+"题目添加题目集添加失败");
                        return Result.failure();
                    }
                }
            }
        }
        System.out.println("题目集新增成功");
        return Result.success("题目集新增成功");
    }

    @GetMapping("/getCollection")
    public Result getCollection(@RequestParam("colId") Integer colId,
                                HttpServletRequest request,
                                HttpServletResponse response) {
        System.out.println("收到获取题目集内容的请求");
        System.out.println("验证token");
        String token = request.getHeader("Authorization");
        Integer userId;
        try {
            DecodedJWT decodedJWT = jwtUtil.verifyToken(token);
            userId = Integer.parseInt(decodedJWT.getClaim("userId").asString());
            System.out.println("token验证成功，userId:"+userId);
        }catch (Exception e){
            System.out.println("token验证失败");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return Result.failure("token验证失败");
        }
        System.out.println("参数验证");
        Collections collection;
        try {
            collection = collectionService.findCollectionById(userId, colId);
            if(collection==null){
                return Result.failure("题目集不存在或题目集不属于该用户");
            }
        }catch (Exception e){
            return Result.failure("数据库查询失败");
        }
        System.out.println("参数验证成功，题目集:"+collection);
        System.out.println("找出题目集包含的题目");
        String problemListStr = collection.getProblemList();
        //将该json字符串转换为List格式
        ObjectMapper objectMapper = new ObjectMapper();
        List<Problem> problemList= new ArrayList<>();
        try {
            List<Map<String, Object>> list=objectMapper.readValue(problemListStr, new TypeReference<List<Map<String, Object>>>() {});
            System.out.println("题目集包含的题目:"+list);
            for (Map<String, Object> object : list){
                //将object的problemId加入到list中
                Problem problem = problemService.findProblemById((Integer) object.get("problemId"));
                if (problem==null){
                    return Result.failure("题目不存在:"+object.get("problemId"));
                }
                problemList.add(problem);
            }
            System.out.println("题目集包含的题目加载成功"+problemList);
//            return Result.success(problemList);
        }catch (Exception e){
            System.out.println("题目集包含的题目解析失败");
            return Result.failure("题目集包含的题目解析失败");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("collection",collection);
        map.put("problemList",problemList);
        return Result.success(map);
    }

    //删除题目集
    @DeleteMapping("/deleteCollection")
    public Result deleteCollection(@RequestParam("colId") Integer colId,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws JsonProcessingException {
        System.out.println("收到删除题目集的请求");
        System.out.println("验证token");
        String token = request.getHeader("Authorization");
        Integer userId;
        try {
            DecodedJWT decodedJWT = jwtUtil.verifyToken(token);
            userId = Integer.parseInt(decodedJWT.getClaim("userId").asString());
            System.out.println("token验证成功，userId:"+userId);
        }catch (Exception e){
            System.out.println("token验证失败");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return Result.failure("token验证失败");
        }
        System.out.println("参数验证");
        if(colId==null){
            return Result.failure("参数错误");
        }
        System.out.println("参数验证通过");
        //删除题目集之前，先把题目后面的的题目集标签删掉
        //找出题目集
        Collections collection;
        try {
            collection = collectionService.findCollectionById(userId, colId);
            if(collection==null) return Result.failure("题目集不存在");
        }
        catch (Exception e){
            return Result.failure("数据库操作失败");
        }
        //找出题目集的题目列表
        List<Map<String, Object>> problemList;
        ObjectMapper mapper = new ObjectMapper();
        try {
            String problemListStr = collection.getProblemList();
            problemList = mapper.readValue(problemListStr, new TypeReference<List<Map<String, Object>>>() {
            });
        }catch (Exception e){
            return Result.failure("题目集包含的题目解析失败");
        }
        //将题目中附带该题目集的题目集标签删掉
        for(Map<String, Object> object:problemList){
            Integer problemId = (Integer) object.get("problemId");
            Problem problem = problemService.findProblemById(problemId);
            if(problem==null){
                System.out.println("题目不存在");
            }
            if(Objects.equals(problem.getUserId(), userId)){
                String collectionListStr = problem.getCollection();
                Set<String> collectionList = mapper.readValue(collectionListStr, new TypeReference<Set<String>>(){});
                if(collectionList.contains(collection.getColName())){
                    collectionList.remove(collection.getColName());
                    problem.setCollection(mapper.writeValueAsString(collectionList));
                    try{
                        if(problemService.updateProblemById(problemId,userId,problem)){
                            System.out.println(problemId+"题目集删除成功");
                        }
                        else {
                            System.out.println(problemId+"题目集删除失败");
                        }
                    }catch (Exception e){
                        System.out.println(problemId+"题目删除题目集失败,数据库错误");
                        return Result.failure("题目集删除失败,数据库错误");
                    }
                }
            }
        }
        try{
            Integer result = collectionService.deleteCollectionById(userId,colId);
            if(result==0) {
                System.out.println("删除题目集成功");
                return Result.success();
            } else if (result==1) {
                System.out.println("该题目集不存在");
                return Result.failure("该题目集不存在");
            } else if (result==2) {
                System.out.println("该题目集不属于该用户");
                return Result.failure("权限不足");
            } else if (result==3) {
                System.out.println("数据库操作发生错误");
                return Result.failure("数据库操作发生错误");
            }else {
                return Result.failure("数据库操作发生错误");
            }
        }catch (Exception e){
            System.out.println("操作异常");
            return Result.failure("操作异常");
        }
    }


    @GetMapping("/getColProblem")
    public Result getColProblem(@RequestParam("colId") Integer colId,
                                HttpServletRequest request,
                                HttpServletResponse response) {
        System.out.println("收到获取题目集内容的请求");
        System.out.println("验证token");
        String token = request.getHeader("Authorization");
        Integer userId;
        try {
            DecodedJWT decodedJWT = jwtUtil.verifyToken(token);
            userId = Integer.parseInt(decodedJWT.getClaim("userId").asString());
            System.out.println("token验证成功，userId:"+userId);
        }catch (Exception e){
            System.out.println("token验证失败");
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return Result.failure("token验证失败");
        }
        System.out.println("参数验证");
        Collections collection;
        try {
            collection = collectionService.findCollectionByColId(colId);
            if(collection==null){
                return Result.failure("题目集不存在");
            }
        }catch (Exception e){
            return Result.failure("数据库查询失败");
        }
        System.out.println("参数验证成功，题目集:"+collection);
        System.out.println("找出题目集包含的题目");
        String problemListStr = collection.getProblemList();
        //将该json字符串转换为List格式
        ObjectMapper objectMapper = new ObjectMapper();
        List<Problem> problemList= new ArrayList<>();
        try {
            List<Map<String, Object>> list=objectMapper.readValue(problemListStr, new TypeReference<List<Map<String, Object>>>() {});
            System.out.println("题目集包含的题目:"+list);
            for (Map<String, Object> object : list){
                //将object的problemId加入到list中
                Problem problem = problemService.findProblemById((Integer) object.get("problemId"));
                if (problem==null){
                    return Result.failure("题目不存在:"+object.get("problemId"));
                }
                problemList.add(problem);
            }
            System.out.println("题目集包含的题目加载成功"+problemList);
        }catch (Exception e){
            System.out.println("题目集包含的题目解析失败");
            return Result.failure("题目集包含的题目解析失败");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("collection",collection);
        map.put("problemList",problemList);
        //找出这个题目集中用户通过的题目
        Set<Integer> problemNum;
        //找出这个题目集中的题目id集合
        List<Integer> pids = new ArrayList<>();
        for(Problem problem:problemList){
            pids.add(problem.getProblemId());
        }
        try {
            problemNum = submissionService.findAllByUserId(userId,pids);
        }catch (Exception e){
            return Result.failure();
        }
        map.put("problemNum", problemNum);
        System.out.println("用户通过的题目列表:"+problemNum);
        return Result.success(map);
    }
}
